package me.xingyannian.zhaopin.listener;

import cn.hutool.core.util.IdcardUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import lombok.extern.slf4j.Slf4j;
import me.xingyannian.zhaopin.dto.PreExamineeDto;
import me.xingyannian.zhaopin.entity.ChangCi;
import me.xingyannian.zhaopin.entity.PreExaminee;

import me.xingyannian.zhaopin.entity.QualityUniversity;
import me.xingyannian.zhaopin.service.PreExamineeService;
import me.xingyannian.zhaopin.service.QualityUniversityService;
import me.xingyannian.zhaopin.util.GuangDongCityUtil;

import java.util.List;

/**
 * @author xingyannian
 */
@Slf4j
public class PreExamineeDtoListener implements ReadListener<PreExamineeDto> {
    private final PreExamineeService preExamineeService;
    private final QualityUniversityService qualityUniversityService;
    // 名校数据
    private final ChangCi changCi;
    /**
     * 每隔5条存储数据库，实际使用中可以100条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 100;
    /**
     * 缓存的数据
     */
    private List<PreExaminee> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    public PreExamineeDtoListener(PreExamineeService preExamineeService, QualityUniversityService qualityUniversityService, ChangCi changCi) {
        this.preExamineeService = preExamineeService;
        this.qualityUniversityService = qualityUniversityService;
        this.changCi = changCi;
    }
    /**
     * When analysis one row trigger invoke function.
     *
     * @param data    one row value. It is same as {@link AnalysisContext#readRowHolder()}
     * @param context analysis context
     */
    @Override
    public void invoke(PreExamineeDto data, AnalysisContext context) {
        log.info("解析到一条数据:{}", data.toString());
        cachedDataList.add(this.getPreExaminee(data, this.changCi));
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 根据传入的预审人员数据对象和数据转换对象，返回对应的预审人员对象
     *
     * @param data 预审人员数据传输对象
     * @param changCi 数据转换对象
     * @return 预审人员对象
     */
    private PreExaminee getPreExaminee(PreExamineeDto data, ChangCi changCi) {
        PreExaminee preExaminee = new PreExaminee();
        preExaminee.setChangCi(changCi);
        preExaminee.setSort(data.getSort());
        // 字符处理，去掉字符两端空格和换行符
        preExaminee.setName(trimString(data.getName()));
        // 身份证号处理，去掉字符两端空格和换行符
        String idCardNo = trimString(data.getIdCardNo());
        preExaminee.setIdCardNo(idCardNo);
        preExaminee.setGender(trimString(data.getGender()));
        preExaminee.setCompany(trimString(data.getCompany()));
        preExaminee.setJobName(trimString(data.getJobName()));
        preExaminee.setJobCode(trimString(data.getJobCode()));
        var bachelorSchool = trimString(data.getBachelorSchool());
        preExaminee.setBachelorSchool(bachelorSchool);
        var qualityUniversity = this.qualityUniversityService.findByName(bachelorSchool);
        if (qualityUniversity != null && !qualityUniversity.isEmpty()) {
            var type = qualityUniversity.get(0).getType();
            preExaminee.setBachelorSchoolType(type);
        }
        var postgraduateSchool = trimString(data.getPostgraduateSchool());
        if (postgraduateSchool != null && !postgraduateSchool.isEmpty()) {
            preExaminee.setPostgraduateSchool(postgraduateSchool);
            var qualityUniversity1 = this.qualityUniversityService.findByName(postgraduateSchool);
            if (qualityUniversity1 != null && !qualityUniversity1.isEmpty()) {
                var type = qualityUniversity1.get(0).getType();
                preExaminee.setPostgraduateSchoolType(type);
            }
        }

        // 从身份证获取省份和城市
        if (IdcardUtil.isValidCard(idCardNo)) {
            String province = IdcardUtil.getProvinceByIdCard(idCardNo);
            preExaminee.setProvince(province);
            if (province.equals("广东")) {
                String city = GuangDongCityUtil.getCityName(idCardNo.substring(0, 4));
                preExaminee.setCity(city);
            }
        } else {
            preExaminee.setProvince("未知");
        }
        return preExaminee;
    }

    /**
     * 在所有分析完成后执行的操作。
     *
     * @param analysisContext 分析上下文对象，包含所有分析的结果和信息。
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成！");
    }
    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据，开始存储数据库！", cachedDataList.size());
        this.preExamineeService.saveAll(cachedDataList);
        log.info("存储数据库成功！");
    }
    // 字符处理，去掉字符两端空格和换行符
    String trimString(String str) {
        return (str != null) ? str.trim() : null;
    }

}
